<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en">
<head>
	<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
	<title>进阶：11、过渡状态 通过组件组织过渡</title>
	<script type="text/javascript" src="https://unpkg.com/vue/dist/vue.js"></script>
	<script src="https://unpkg.com/tween.js@16.3.4"></script>
</head>
<body>
	<div id="example-8">
	  <input v-model.number="firstNumber" type="number" step="20"> +
	  <input v-model.number="secondNumber" type="number" step="20"> =
	  {{ result }}
	  <p>
	    <animated-integer v-bind:value="firstNumber"></animated-integer> +
	    <animated-integer v-bind:value="secondNumber"></animated-integer> =
	    <animated-integer v-bind:value="result"></animated-integer>
	  </p>
	</div>

	<script type="text/javascript">
		// 过渡依赖于数据的变化，如果一个组件中有很多的过渡效果那么比如依赖的数据项也是很多的，
		// 复杂到一定程度会让组件看起来臃肿不堪，也不利于我们对正常业务逻辑的处理，有什么办法？
		// 
		// 前面我们不是尝试过将过渡封装在组件里面吗？如果我们把过渡的动画效果提取到组件中，
		// 问题是不是迎刃而解了呢！
		// 这种复杂的补间动画逻辑可以被复用
		// 任何整数都可以执行动画
		// 组件化使我们的界面十分清晰
		// 可以支持更多更复杂的动态过渡
		// strategies.
		Vue.component('animated-integer', {
		  template: '<span>{{ tweeningValue }}</span>',
		  props: {
		    value: {
		      type: Number,
		      required: true
		    }
		  },
		  data: function () {
		    return {
		      tweeningValue: 0
		    }
		  },
		  watch: {
		    value: function (newValue, oldValue) {
		      this.tween(oldValue, newValue)
		    }
		  },
		  mounted: function () {
		    this.tween(0, this.value)
		  },
		  methods: {
		    tween: function (startValue, endValue) {
		      var vm = this
		      function animate (time) {
		        requestAnimationFrame(animate)
		        TWEEN.update(time)
		      }
		      new TWEEN.Tween({ tweeningValue: startValue })
		        .to({ tweeningValue: endValue }, 500)
		        .onUpdate(function () {
		          vm.tweeningValue = this.tweeningValue.toFixed(0)
		        })
		        .start()
		      animate()
		    }
		  }
		})

		// All complexity has now been removed from the main Vue instance!
		// 看看组件封装后的实例化父组件，简单清晰明了
		new Vue({
		  el: '#example-8',
		  data: {
		    firstNumber: 20,
		    secondNumber: 40
		  },
		  computed: {
		    result: function () {
		      return this.firstNumber + this.secondNumber
		    }
		  }
		})		
	</script>
</body>
</html>